﻿
using DapperExtensions;
using MySql.Data.MySqlClient;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using Dapper;

namespace Model
{
    /// <summary>
    /// DataModel扩展类，实现Lambda表达式操作数据库
    /// </summary>
    public static class ModelExt
    {
        #region 获取数据

        /// <summary>
        /// 无排序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static List<T> Select<T>(this T entity, Expression<Func<T, bool>> func) where T : BaseEntity<T>
        {
            return entity.DataResp.GetList(func, null).ToList();
        }
        /// <summary>
        /// 排序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="func"></param>
        /// <param name="Sort"></param>
        /// <returns></returns>
        public static List<T> Select<T>(this T entity, Expression<Func<T, bool>> func, Sorting<T> Sort) where T : BaseEntity<T>
        {
            return entity.DataResp.GetList(func, new Sorting<T>[] { Sort }).ToList();
        }
        /// <summary>
        /// 排序
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="func"></param>
        /// <param name="Sort"></param>
        /// <returns></returns>
        public static List<T> Select<T>(this T entity, Expression<Func<T, bool>> func, Sorting<T>[] Sorts) where T : BaseEntity<T>
        {
            return entity.DataResp.GetList(func, Sorts).ToList();
        }
        /// <summary>
        /// 按照分页请求数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="expression"></param>
        /// <param name="sorts"></param>
        /// <param name="page"></param>
        /// <param name="resultsPerPage"></param>
        /// <param name="isTotal"></param>
        /// <param name="total"></param>
        /// <returns></returns>
        public static List<T> SelectPage<T>(this T entity, Expression<Func<T, bool>> expression, Sorting<T> sort, int page, int resultsPerPage,
            ref int total) where T : BaseEntity<T>
        {
            Sorting<T>[] sorts = new Sorting<T>[] { sort };
            bool isTotal = true;
            return entity.DataResp.GetPage(expression, sorts, page, resultsPerPage, isTotal, ref total).ToList();
        }
        /// <summary>
        /// 按照分页请求数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="expression"></param>
        /// <param name="sorts"></param>
        /// <param name="page"></param>
        /// <param name="resultsPerPage"></param>
        /// <param name="isTotal"></param>
        /// <param name="total"></param>
        /// <returns></returns>
        public static List<T> SelectPage<T>(this T entity, Expression<Func<T, bool>> expression, Sorting<T>[] sorts, int page, int resultsPerPage,
            ref int total) where T : BaseEntity<T>
        {
            bool isTotal = true;
            return entity.DataResp.GetPage(expression, sorts, page, resultsPerPage, isTotal, ref total).ToList();
        }

        //public static List<T> SelectPage(this T entity, Expression<Func<T, bool>> expression, Sorting<T>[] sorts, int page, int resultsPerPage,
        //    bool isTotal, ref int total) where T : BaseEntity<T>
        //{
        //    return new List<T>;
        //}

        /// <summary>
        /// 获取满足条件的第一个记录,不要用Get,改用Select更快，不知道为什么
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="func"></param>
        /// <returns></returns>
        public static T Get<T>(this T entity, Expression<Func<T, bool>> func) where T : BaseEntity<T>
        {
            //return entity.DataResp.Get<T>(func);
            List<T> lst = entity.DataResp.GetList(func, null).ToList();
            if (lst == null || lst.Count == 0) return null;
            return lst[0];
        }

        /// <summary>
        /// 根据表达式查询实体的数量
        /// </summary>
        /// <param name="func"></param>
        /// <returns></returns>
        public static int Count<T>(this T entity, Expression<Func<T, bool>> func) where T : BaseEntity<T>
        {
            return entity.DataResp.Count(func);
        }
        /// <summary>
        /// 直接执行Sql查询语句
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="Sql"></param>
        /// <returns></returns>
        public static List<T> Query<T>(this T entity, string Sql) where T : BaseEntity<T>
        {
            return entity.DataResp.Context.DB.Query<T>(Sql).ToList();

        }
        //2018-5-29 modify by csm
        public static U SqlQuerySimple<T, U>(this T entiry, string Sql) where T : BaseEntity<T> where U : struct
        {
            try
            {
                List<U> lst = entiry.DataResp.Context.DB.Query<U>(Sql, null).ToList();
                if (lst.Count >= 0) return lst[0];
                else return default(U);
            }
            catch (Exception)
            {
                return default(U);
            }
        }
        //modify by caism 2019-09-20
        public static string SqlQuerySimple3<T>(this T entiry, string Sql) where T : BaseEntity<T>
        {
            try
            {
                string res = entiry.DataResp.Context.DB.QueryFirst<string>(Sql, null);
                return res;
            }
            catch (Exception)
            {
                return "";
            }
        }
        //2019-04-29 modify by csm
        public static U SqlQuerySimple2<T, U>(this T entiry, string Sql) where T : BaseEntity<T> where U : struct
        {
            try
            {
                return entiry.DataResp.Context.DB.QuerySingle<U>(new CommandDefinition(Sql));
            }
            catch (Exception)
            {
                return default(U);
            }
        }

        #endregion

        #region 修改数据
        /// <summary>
        /// 更新自己（根据关键词修改）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static bool UpdateSelf<T>(this T entity) where T : BaseEntity<T>
        {
            return entity.DataResp.Update(entity.ToPropertyParam());
        }

        /// <summary>
        /// 更新自己（根据关键词修改,并且排除主索引字段）by caism 20180724
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static bool UpdateSelfNoID<T>(this T entity, string IDKey) where T : BaseEntity<T>
        {
            return entity.DataResp.Update(entity.ToPropertyParamNoIDKey(IDKey));
        }
        /// <summary>
        /// 带条件更新所有字段
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static bool Update<T>(this T entity, Expression<Func<T, bool>> func) where T : BaseEntity<T>
        {
            return entity.DataResp.Update(func, (entity.ToPropertyParam()));
        }
        /// <summary>
        /// 带条件更新指定字段
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static bool UpdateAField<T>(this T entity, Expression<Func<T, bool>> func, DbFiled<T> filed = null) where T : BaseEntity<T>
        {
            return entity.DataResp.Update(func, new DbFiled<T>[] { filed });
        }
        /// <summary>
        /// 带条件更新指定字段
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static bool UpdateAnyField<T>(this T entity, Expression<Func<T, bool>> func, params DbFiled<T>[] fileds) where T : BaseEntity<T>
        {
            return entity.DataResp.Update(func, fileds);
        }
        #endregion

        #region 插入数据
        public static bool Insert<T>(this T entity, Expression<Func<T, object>> primaryKey = null) where T : BaseEntity<T>
        {
            return entity.DataResp.Insert(entity, primaryKey);
        }

        public static bool Insert<T>(this T entity, string keyField) where T : BaseEntity<T>
        {
            return entity.DataResp.Insert(entity, keyField);
        }
        #endregion

        public static bool Delete<T>(this T entity, Expression<Func<T, bool>> func) where T : BaseEntity<T>
        {
            return entity.DataResp.Delete(func);
        }
        /// <summary>
        /// 直接执行Sql语句（不返回，无参数）
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public static object ExecSql<T>(this T entity, string sql) where T : BaseEntity<T>
        {
            return entity.DataResp.Context.DB.ExecuteScalar(sql);
        }
        /// <summary>
        /// 获取友好的日期时间
        /// </summary>
        /// <param name="dtStr"></param>
        /// <returns></returns>
        public static string GetFriendDataTime(this object ob, string dateStr)
        {
            DateTime dt = DateTime.MinValue;
            DateTime.TryParse(dateStr, out dt);
            TimeSpan sp = DateTime.Now - dt;
            if (sp.TotalDays < 1)
            {
                if (sp.TotalMinutes < 15) return ("刚刚");
                else if (sp.TotalHours < 1)
                    return $"{(int)sp.TotalMinutes} 分钟前";
                else return $"{(int)sp.TotalHours} 小时前";
            }
            else if (sp.TotalDays < 2) return "昨天";
            else if (sp.TotalDays < 31) return $"{(int)sp.TotalDays} 天前";
            else if (sp.TotalDays < 60) return "上个月";
            else return $"{(int)(sp.TotalDays / 30)}个月前";
        }

    }
}
